package com.higgins.eventtracking.server.projectmanagement;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;

import com.higgins.eventtracking.client.SecurityAccessDeniedException;
import com.higgins.eventtracking.client.dto.MealDTO;
import com.higgins.eventtracking.client.dto.TransactionDTO;
import com.higgins.eventtracking.client.projectmanagement.HistoryItemDTO;
import com.higgins.eventtracking.client.projectmanagement.ProjectItemDTO;
import com.higgins.eventtracking.client.projectmanagement.ProjectService;
import com.higgins.eventtracking.server.DataStoreService;
import com.higgins.eventtracking.server.DateUtility;
import com.higgins.eventtracking.server.DietTrackingDataService;
import com.higgins.eventtracking.server.FinanceTrackingDataService;
import com.higgins.eventtracking.server.GenericDataStoreService;
import com.higgins.eventtracking.server.PMF;
import com.higgins.eventtracking.server.dataModel.Consumption;
import com.higgins.eventtracking.server.dataModel.HealthEvent;
import com.higgins.eventtracking.server.dataModel.Meal;
import com.higgins.eventtracking.server.dataModel.TrackingEvent;

public class ProjectDataSource extends GenericDataStoreService implements ProjectService	 {
	PersistenceManager pm;

	public void openConnection()	{
		pm=PMF.get().getPersistenceManager();
	}

	public void closeConnection()	{
		pm.close();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<ProjectItemDTO> retrieveProjectItems(Long parentId)
			throws IllegalArgumentException {
//		addTestData();
		
		List<ProjectItemDTO> dtoResults = new ArrayList<ProjectItemDTO>();
		if (parentId == null)	{
			Query query=pm.newQuery(ProjectItem.class, "task == taskParam");
			query.declareParameters("String taskParam");
			query.setOrdering("priority ascending");
			List<ProjectItem> results = (List<ProjectItem>)query.execute("Projects");
			for (ProjectItem result:results)	{
				result = pm.detachCopy(result);
				if (isPermanent(result) || isNotComplete(result))
					dtoResults.add(result.getDTO());
			}
			return dtoResults;
		} else	{
			Query query=pm.newQuery(ProjectItem.class, "parentId == parentIdParam");
			query.declareParameters("Long parentIdParam");
			query.setOrdering("priority ascending");
			List<ProjectItem> children = (List<ProjectItem>)query.execute(parentId);
			for(ProjectItem child:children)	{
				if (isPermanent(child) || isNotComplete(child))
					dtoResults.add(child.getDTO());
			}
			return dtoResults;
		}
	}
	
	private Boolean isPermanent(ProjectItem projectItem)	{
		if (projectItem.getPermanent()!=null)	{
			return projectItem.getPermanent();
		} else 	{
			return false; 
		}
	}
	private Boolean isNotComplete(ProjectItem projectItem)	{
		if ((projectItem.getComplete()==null) || (projectItem.getComplete() < 100.0))	{
			return true;
		}	else {
			return false;
		}
	}
	private Boolean isImmediate(ProjectItem projectItem)	{
		if (projectItem.getImmediate()!=null)	{
			return projectItem.getPermanent();
		} else 	{
			return false; 
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<ProjectItem> retrievePersistentProjectItems(Long parentId)
	throws IllegalArgumentException {
		Query query=pm.newQuery(ProjectItem.class, "parentId == parentIdParam");
		query.declareParameters("Long parentIdParam");
		query.setOrdering("priority ascending");
		List<ProjectItem> children = (List<ProjectItem>)query.execute(parentId);
		return children;
	}	

	@Override
	public List<Long> retrieveParentIds(Long childId)
			throws IllegalArgumentException {
		Long parentId = new Long(0);
		List<Long> parentIds = new ArrayList<Long>();
		if (childId!=null)	{
			parentId = childId;
			while (parentId!=null)	{
				ProjectItem item = null;
				try	{
					item = pm.getObjectById(ProjectItem.class, parentId);
					parentIds.add(parentId);
					parentId = item.getParentId();
				} catch (Exception e)	{
					parentId = null;
				}
			}
		}
		return parentIds;
	}
	
	
	@Override
	public Long insetProjectItem(ProjectItemDTO item)
			throws IllegalArgumentException {
		
		ProjectItem parent = new ProjectItem();
		parent.update(item);
		parent.setStartTimestamp(new Date());
		pm.makePersistent(parent);
		return parent.getId();
	}

	@Override
	public Long updateProjectItemTask(Long id, String task, Long parentId)
			throws IllegalArgumentException {
		if (id != null)	{
			ProjectItem item = pm.getObjectById(ProjectItem.class, id);
			item.setTask(task);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			return item.getId();
		} else	{
			ProjectItem item = new ProjectItem();
			item.setParentId(parentId);
			item.setTask(task);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			return item.getId();
		}
	}
	
	@Override
	public Long updateFollowUpDate(Long id, String followUpDateString)
			throws IllegalArgumentException {
		Date followUpDate = DateUtility.convertStringToDate(followUpDateString);
		if (id != null)	{
			ProjectItem item = pm.getObjectById(ProjectItem.class, id);
			item.setFollowUpDate(followUpDate);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			return item.getId();
		} 
		return null;
	}	

	@Override
	public Long updateStartTimestamp(Long id, Date startTimestamp)
			throws IllegalArgumentException {
		if (id != null)	{
			ProjectItem item = pm.getObjectById(ProjectItem.class, id);
			item.setStartTimestamp(startTimestamp);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			return item.getId();
		} 
		return null;
	}	
	
	@Override
	public Long updateEndTimestamp(Long id, Date endTimestamp)
			throws IllegalArgumentException {
		if (id != null)	{
			ProjectItem item = pm.getObjectById(ProjectItem.class, id);
			item.setEndTimestamp(endTimestamp);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			return item.getId();
		} 
		return null;
	}		
	@Override
	public Long updateProjectItemForecast(Long id, Double forecast, Long parentId)
			throws IllegalArgumentException {
		if (id != null)	{
			ProjectItem item = pm.getObjectById(ProjectItem.class, id);
			item.setForecast(forecast);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			updateParentForecasts(id);
			updateParentCompletes(id);
			return item.getId();
		} else	{
			ProjectItem item = new ProjectItem();
			item.setParentId(parentId);
			item.setForecast(forecast);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			updateParentForecasts(item.getId());
			updateParentCompletes(item.getId());
			return item.getId();
		}
	}

	@Override
	public Long updateProjectItemComplete(Long id, Double complete, Long parentId)
			throws IllegalArgumentException {
		if (id != null)	{
			ProjectItem item = pm.getObjectById(ProjectItem.class, id);
			item.setComplete(complete);
			if (complete > 99.0)	{
				item.setEndTimestamp(new Date());
			}
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			updateParentCompletes(id);
			return item.getId();
		} else	{
			ProjectItem item = new ProjectItem();
			item.setParentId(parentId);
			item.setComplete(complete);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();
			updateParentCompletes(item.getId());
			return item.getId();
		}
	}
	
	@Override
	public List<Long> updateProjectItemPriority(Long idOne, Integer priorityOne, Long idTwo, Integer priorityTwo, Long parentId)
			throws IllegalArgumentException {
		if (idOne != null)	{
			try	{
				List<Long> list = new ArrayList<Long>();
				
				ProjectItem item = pm.getObjectById(ProjectItem.class, idOne);
				item.setPriority(priorityOne);
				Transaction transaction = pm.currentTransaction();
				if (transaction.getOptimistic())
					System.out.println("OPTIMISTIC!!!");
				if (transaction.isActive())
					System.out.println("ACTIVE!!!");
				while (transaction.getOptimistic())
					pause();
				transaction.begin();
				pm.makePersistent(item);
				transaction.commit();
				list.add(item.getId());
				
				item = pm.getObjectById(ProjectItem.class, idTwo);
				item.setPriority(priorityTwo);
				transaction = pm.currentTransaction();
				if (transaction.getOptimistic())
					System.out.println("OPTIMISTIC!!!");
				if (transaction.isActive())
					System.out.println("ACTIVE!!!");
				while (transaction.getOptimistic())
					pause();
				transaction.begin();
				pm.makePersistent(item);
				transaction.commit();
				list.add(item.getId());
				
				return list;
				
			} catch (Exception e)	{
/*				ProjectItem item = pm.getObjectById(ProjectItem.class, id);
				item.setPriority(priority);
				Transaction transaction = pm.currentTransaction();
				if (transaction.getOptimistic())
					System.out.println("OPTIMISTIC!!!");
				if (transaction.isActive())
					System.out.println("ACTIVE!!!");
				while (transaction.getOptimistic())
					pause();
				transaction.begin();
				pm.makePersistent(item);
				transaction.commit();*/
				return null;
			}
		} else	{	/*
			ProjectItem item = new ProjectItem();
			item.setParentId(parentId);
			item.setPriority(priority);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(item);
			transaction.commit();	*/
			return null;
		}
	}
	
	private void pause()	{
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			System.out.println("Pause!!!!!");
			e.printStackTrace();
		}
	}
	
	@Override
	public Boolean deleteProjectItem(Long id) throws IllegalArgumentException {
		// TODO Auto-generated method stub
		ProjectItem item = pm.getObjectById(ProjectItem.class, id);
		Transaction transaction = pm.currentTransaction();
		transaction.begin();
		pm.deletePersistent(item);
		transaction.commit();
		return true;
	}

	@SuppressWarnings("unchecked")
	private List<Effort> retrieveOpenEfforts(Long id)	{
		Query query = pm.newQuery(Effort.class);
		query.declareParameters("Long parentIdParam");
		query.setFilter("parentId == parentIdParam");
		query.setFilter("stop == null");
		List<Effort> efforts = (List<Effort>) query.execute(id);
		for (Effort effort:efforts)	{
			if (!id.equals(effort.getParentId()))
				efforts.remove(effort);
		}
		return efforts;
	}

	@SuppressWarnings("unchecked")
	private List<Effort> retrieveAllEfforts(Long id)	{
		Query query = pm.newQuery(Effort.class);
		query.declareParameters("Long parentIdParam");
		query.setFilter("parentId == parentIdParam");
		List<Effort> efforts = (List<Effort>) query.execute(id);
		return efforts;
	}
	
	@Override 
	public String retrieveTodaysSimpleFormatDate()	{
		String pattern = "dd/MM/yyyy";
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(new Date());
	}
	
	private boolean historyArrayContains(List<HistoryItemDTO> list, String historyText)	{
		for (HistoryItemDTO historyItem:list)	{
			if (historyItem.getDescription().equals(historyText))
				return true;
		}
		return false;
	}
	
	@Override
	public List<String> retrieveImmediate()	{
		Query query = pm.newQuery(ProjectItem.class);
		query.declareParameters("Boolean immediateParam");
		query.setFilter("immediate == immediateParam");
		List<ProjectItem> projectItems = (List<ProjectItem>) query.execute(true);
		List<String> immediateItems = new ArrayList<String>();
		for (ProjectItem projectItem:projectItems)	{
			if (isNotComplete(projectItem))	{
				immediateItems.add(projectItem.getTask());
			}
		}
		return immediateItems;
	}
	@Override
	public List<String> retrieveFollowUp()	{
		Query query = pm.newQuery(ProjectItem.class);
		query.declareParameters("Boolean followUpParam");
		query.setFilter("followUp == followUpParam");
		List<ProjectItem> projectItems = (List<ProjectItem>) query.execute(true);
		List<String> followUpItems = new ArrayList<String>();
		for (ProjectItem projectItem:projectItems)	{
			if (isNotComplete(projectItem) && isFollowUpDatePast(projectItem))	{
				followUpItems.add(projectItem.getTask());
			}
		}
		return followUpItems;
	}
	
	private Boolean isFollowUpDatePast(ProjectItem projectItem)	{
		if (projectItem.getFollowUpDate()!=null && projectItem.getFollowUpDate().after(new Date()))	{
			return false;
		} else 	{
			return true;
		}
	}
	
	@Override
	public List<HistoryItemDTO> retrieveHistory(String dateStr, Boolean showAllEvents, Boolean showDistinctList)	{
		String pattern = "dd/MM/yyyy";
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		Date date = new Date();
		try	{
			date = format.parse(dateStr);
		} catch (Exception e)	{
			
		}
		
		List<HistoryItemDTO> history = new ArrayList<HistoryItemDTO>();
		
		List<Effort> efforts = retrieveAllEfforts(DateUtility.getStartOfDay(date), DateUtility.getEndOfDay(date));
		
		for (Effort effort:efforts)	{
			Long projectItemId = effort.getParentId();
			String historyText = "";
			
			List<Long> parentIds = retrieveParentIds(projectItemId);
			for (Long parendId:parentIds) {
				ProjectItem projectItem = pm.getObjectById(ProjectItem.class, parendId);
				historyText = projectItem.getTask() + (historyText.equals("")?"":" -> ") + historyText; 
			}
			
			String effortStart = effort.getStart()!=null?effort.getStart().toString().substring(0, (effort.getStart().toString().length()-9)):"";
			String effortStop = effort.getStop()!=null?effort.getStop().toString().substring(10, (effort.getStop().toString().length()-9)):"";
			
			if (!showDistinctList)
				historyText = effortStart + " to " + effortStop + ": " + historyText;

			HistoryItemDTO historyItemDTO = new HistoryItemDTO();
			historyItemDTO.setDescription(historyText);
			historyItemDTO.setTimestamp(effort.getStart());
			if (showDistinctList)	{
				if (!historyArrayContains(history, historyText))	{
					history.add(historyItemDTO);
				}
			} else {
				history.add(historyItemDTO);
			}
		}
		
		if (showAllEvents)	{
			FinanceTrackingDataService financeDataSource = new FinanceTrackingDataService();
			financeDataSource.openPersistenceManager();
			List<TransactionDTO> transactions = financeDataSource.retrieveTransactions(DateUtility.getStartOfDay(date), DateUtility.getEndOfDay(date));
	
			for (TransactionDTO transaction:transactions)	{
				String historyText = transaction.getTimestamp().toString() + " - " + transaction.toString();
				HistoryItemDTO historyItemDTO = new HistoryItemDTO();
				historyItemDTO.setDescription(historyText);
				historyItemDTO.setTimestamp(transaction.getTimestamp());
				history.add(historyItemDTO);
			}
			financeDataSource.closePersistenceManager();
			
			DietTrackingDataService dietTrackingDataService = new DietTrackingDataService();
			dietTrackingDataService.openPersistenceManager();
			List<Consumption> meals = dietTrackingDataService.retrieveConsumption(DateUtility.getStartOfDay(date), DateUtility.getEndOfDay(date));
			for (Consumption meal:meals)	{
				meal.getMeal();
				HistoryItemDTO historyItemDTO = new HistoryItemDTO();
				historyItemDTO.setTimestamp(meal.getTimeStamp());
				historyItemDTO.setDescription(meal.getTimeStamp().toString() + " - " + meal.getMeal());
				history.add(historyItemDTO);
			}
			dietTrackingDataService.closePersistenceManager();
	
			DataStoreService dataSourceService = new DataStoreService();
			dataSourceService.openPersistenceManager();
			List<TrackingEvent> trackingEvents = dataSourceService.retrieveTrackingEvents(DateUtility.getStartOfDay(date), DateUtility.getEndOfDay(date));
			for (TrackingEvent trackingEvent:trackingEvents)	{
				HistoryItemDTO historyItemDTO = new HistoryItemDTO();
				historyItemDTO.setTimestamp(trackingEvent.getTimeStamp());
				historyItemDTO.setDescription(trackingEvent.getTimeStamp().toString() + " - " + trackingEvent.toString());
				history.add(historyItemDTO);
			}
			dataSourceService.openPersistenceManager();
			List<HealthEvent> healthEvents = dataSourceService.retrieveHealthEvents(DateUtility.getStartOfDay(date), DateUtility.getEndOfDay(date));
			for (HealthEvent healthEvent:healthEvents)	{
				HistoryItemDTO historyItemDTO = new HistoryItemDTO();
				historyItemDTO.setTimestamp(healthEvent.getTimestamp());
				historyItemDTO.setDescription(healthEvent.getTimestamp().toString() + " - " + healthEvent.toString());
				history.add(historyItemDTO);
			}
			dataSourceService.closePersistenceManager();
		}	
		if (showDistinctList)	{
			Collections.sort(history, new alphaComparator());
		} else {
			Collections.sort(history);
		}
		return history;
	}


	
	public class alphaComparator implements Comparator<HistoryItemDTO> {
	    final public int compare(HistoryItemDTO object1, HistoryItemDTO object2) {
	        return object1.getDescription().compareTo(object2.getDescription());
	    }
	}
	
	
	private List<Effort> retrieveAllEfforts(Date startDate, Date endDate)	{
		Query query = pm.newQuery(Effort.class);
		query.declareParameters("java.util.Date startDateParam, java.util.Date endDateParam");
		query.setFilter("start > startDateParam && start < endDateParam");
		List<Effort> efforts = (List<Effort>) query.execute(startDate, endDate);
//		List<Effort> efforts = (List<Effort>) query.execute();
		return efforts;
	}
	
	@Override
	public Boolean startTimer(Long id) throws IllegalArgumentException {
		stopTimer(null);
		if (id!=null)	{
			Effort effort = new Effort(id, new Date());
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(effort);
			transaction.commit();
		}
		return true;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Boolean stopTimer(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			List<Effort> efforts = retrieveOpenEfforts(id);
			for (Effort effort:efforts)	{
				effort.setStop(new Date());
				Transaction transaction = pm.currentTransaction();
				transaction.begin();
				pm.makePersistent(effort);
				transaction.commit();
			}
		} else {
			Query query = pm.newQuery(Effort.class);
			query.setFilter("stop == null");
			List<Effort> results = (List<Effort>)query.execute();
			for (Effort effort:results)	{
				effort.setStop(new Date());
				Transaction transaction = pm.currentTransaction();
				transaction.begin();
				pm.makePersistent(effort);
				transaction.commit();
			}
		}
		updateActual(id);
		updateParentActuals(id);
		return true;
	}
	
	@Override
	public Boolean setNotPermanent(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			requestedItem.setPermanent(false);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(requestedItem);
			transaction.commit();
		}
		return true;
	}
	
	@Override
	public Boolean setPermanent(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			requestedItem.setPermanent(true);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(requestedItem);
			transaction.commit();
		}
		return true;
	} 
	
	@Override
	public Boolean setNotImmediate(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			requestedItem.setImmediate(false);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(requestedItem);
			transaction.commit();
		}
		return true;
	}
	
	@Override
	public Boolean setImmediate(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			requestedItem.setImmediate(true);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(requestedItem);
			transaction.commit();
		}
		return true;
	} 	
	@Override
	public Boolean setNotFollowUp(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			requestedItem.setFollowUp(false);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(requestedItem);
			transaction.commit();
		}
		return true;
	}
	
	@Override
	public Boolean setFollowUp(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			requestedItem.setFollowUp(true);
			Transaction transaction = pm.currentTransaction();
			transaction.begin();
			pm.makePersistent(requestedItem);
			transaction.commit();
		}
		return true;
	} 		
	
	private void updateActual(Long id)	{
		if (id!=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			List<Effort> efforts = retrieveAllEfforts(id);
			Double totalEffort = 0.0;
			for (Effort effort:efforts)
				totalEffort = totalEffort + effort.getDuration();
			requestedItem.setActual(totalEffort);
			updateProjectItem(requestedItem);
			pause();
		}
	}	
	
	private void updateParentActuals(Long id)	{
		if (id !=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			ProjectItem parentItem = null;
			do	{
				parentItem = pm.getObjectById(ProjectItem.class, requestedItem.getParentId());
				Double total = 0.0;
				for (ProjectItem childItem:retrievePersistentProjectItems(parentItem.getId()))
					total = total + childItem.getActual();
				parentItem.setActual(total);
				updateProjectItem(parentItem);
				parentItem = pm.getObjectById(ProjectItem.class, parentItem.getParentId());
				pause();
			} while (parentItem.getParentId()!=null);
		}
	}

	private void updateParentForecasts(Long id)	{
		if (id !=null)	{
			ProjectItem parentItem = null;
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			do	{
				parentItem = pm.getObjectById(ProjectItem.class, requestedItem.getParentId());
				Double total = 0.0;
				for (ProjectItem childItem:retrievePersistentProjectItems(parentItem.getId()))
					total = total + childItem.getForecast();
				parentItem.setForecast(total);
				updateProjectItem(parentItem);
				pause();
			} while (parentItem.getParentId()!=null);
		}
	}
	
	
	private void updateParentCompletes(Long id)	{
		if (id !=null)	{
			ProjectItem requestedItem = pm.getObjectById(ProjectItem.class, id);
			ProjectItem parentItem = null;
			do	{
				parentItem = pm.getObjectById(ProjectItem.class, requestedItem.getParentId());
				Double totalForecast = 0.0;
				Double totalComplete = 0.0;
				for (ProjectItem childItem:retrievePersistentProjectItems(parentItem.getId()))	{
					totalForecast = totalForecast + (childItem.getForecast()!=null?childItem.getForecast():0.0);
					totalComplete = totalComplete + ((childItem.getForecast()!=null?childItem.getForecast():0.0) * ((childItem.getComplete()!=null?childItem.getComplete():0.0)/100.0));
				}
				parentItem.setComplete(100.0*totalComplete/totalForecast);
				updateProjectItem(parentItem);
				pause();
			} while (parentItem.getParentId()!=null);
		}
	}

	private void updateProjectItem(ProjectItem projectItem)	{
		Transaction transaction = pm.currentTransaction();
		transaction.begin();
		pm.makePersistent(projectItem);
		transaction.commit();
	}

	@Override
	public Long isActive(Long id) throws IllegalArgumentException {
		if (id!=null)	{
			List<Effort> efforts = retrieveOpenEfforts(id);
			if (efforts.size()>0)
				return id;
		}
		return null;
	}

	@Override
	public Boolean checkAccess() throws IllegalArgumentException {
		try	{
			checkAuthority();			
			return true;
		} catch (SecurityAccessDeniedException e)	{
			return false;
		}
	}


}
